/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package controladores;

import controladores.exceptions.NonexistentEntityException;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import entidades.ModeloRepuesto;
import entidades.IngresoRepuesto;
import java.util.ArrayList;
import java.util.List;
import entidades.CambioDeRepuestos;
import entidades.Repuesto;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

/**
 *
 * @author g
 */
public class RepuestoJpaController implements Serializable {

    public static final int NRO_PARTE = 1;
    public static final int DESCRIPCION = 2;

    public RepuestoJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Repuesto repuesto) {
//        if (repuesto.getLs_ingresos() == null) {
//            repuesto.setLs_ingresos(new ArrayList<IngresoRepuesto>());
//        }
//        if (repuesto.getLs_cambios() == null) {
//            repuesto.setLs_cambios(new ArrayList<CambioDeRepuestos>());
//        }
        EntityManager em = null;
        try {
//            em = getEntityManager();
//            em.getTransaction().begin();
//            ModeloRepuesto modeloRepuesto = repuesto.getModeloRepuesto();
//            if (modeloRepuesto != null) {
//                modeloRepuesto = em.getReference(modeloRepuesto.getClass(), modeloRepuesto.getId());
//                repuesto.setModeloRepuesto(modeloRepuesto);
//            }
//            List<IngresoRepuesto> attachedLs_ingresos = new ArrayList<IngresoRepuesto>();
//            for (IngresoRepuesto ls_ingresosIngresoRepuestoToAttach : repuesto.getLs_ingresos()) {
//                ls_ingresosIngresoRepuestoToAttach = em.getReference(ls_ingresosIngresoRepuestoToAttach.getClass(), ls_ingresosIngresoRepuestoToAttach.getId());
//                attachedLs_ingresos.add(ls_ingresosIngresoRepuestoToAttach);
//            }
//            repuesto.setLs_ingresos(attachedLs_ingresos);
//            List<CambioDeRepuestos> attachedLs_cambios = new ArrayList<CambioDeRepuestos>();
//            for (CambioDeRepuestos ls_cambiosCambioDeRepuestosToAttach : repuesto.getLs_cambios()) {
//                ls_cambiosCambioDeRepuestosToAttach = em.getReference(ls_cambiosCambioDeRepuestosToAttach.getClass(), ls_cambiosCambioDeRepuestosToAttach.getId());
//                attachedLs_cambios.add(ls_cambiosCambioDeRepuestosToAttach);
//            }
//            repuesto.setLs_cambios(attachedLs_cambios);
//            em.persist(repuesto);
//            if (modeloRepuesto != null) {
//                modeloRepuesto.getLs_repuestos().add(repuesto);
//                modeloRepuesto = em.merge(modeloRepuesto);
//            }
//            for (IngresoRepuesto ls_ingresosIngresoRepuesto : repuesto.getLs_ingresos()) {
//                Repuesto oldRepuestoOfLs_ingresosIngresoRepuesto = ls_ingresosIngresoRepuesto.getRepuesto();
//                ls_ingresosIngresoRepuesto.setRepuesto(repuesto);
//                ls_ingresosIngresoRepuesto = em.merge(ls_ingresosIngresoRepuesto);
//                if (oldRepuestoOfLs_ingresosIngresoRepuesto != null) {
//                    oldRepuestoOfLs_ingresosIngresoRepuesto.getLs_ingresos().remove(ls_ingresosIngresoRepuesto);
//                    oldRepuestoOfLs_ingresosIngresoRepuesto = em.merge(oldRepuestoOfLs_ingresosIngresoRepuesto);
//                }
//            }
//            for (CambioDeRepuestos ls_cambiosCambioDeRepuestos : repuesto.getLs_cambios()) {
//                Repuesto oldRepuestoOfLs_cambiosCambioDeRepuestos = ls_cambiosCambioDeRepuestos.getRepuesto();
//                ls_cambiosCambioDeRepuestos.setRepuesto(repuesto);
//                ls_cambiosCambioDeRepuestos = em.merge(ls_cambiosCambioDeRepuestos);
//                if (oldRepuestoOfLs_cambiosCambioDeRepuestos != null) {
//                    oldRepuestoOfLs_cambiosCambioDeRepuestos.getLs_cambios().remove(ls_cambiosCambioDeRepuestos);
//                    oldRepuestoOfLs_cambiosCambioDeRepuestos = em.merge(oldRepuestoOfLs_cambiosCambioDeRepuestos);
//                }
//            }
//            em.getTransaction().commit();
            em = getEntityManager();
            em.getTransaction().begin();
            em.persist(repuesto);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Repuesto repuesto) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
//            em = getEntityManager();
//            em.getTransaction().begin();
//            Repuesto persistentRepuesto = em.find(Repuesto.class, repuesto.getId());
//            ModeloRepuesto modeloRepuestoOld = persistentRepuesto.getModeloRepuesto();
//            ModeloRepuesto modeloRepuestoNew = repuesto.getModeloRepuesto();
//            List<IngresoRepuesto> ls_ingresosOld = persistentRepuesto.getLs_ingresos();
//            List<IngresoRepuesto> ls_ingresosNew = repuesto.getLs_ingresos();
//            List<CambioDeRepuestos> ls_cambiosOld = persistentRepuesto.getLs_cambios();
//            List<CambioDeRepuestos> ls_cambiosNew = repuesto.getLs_cambios();
//            if (modeloRepuestoNew != null) {
//                modeloRepuestoNew = em.getReference(modeloRepuestoNew.getClass(), modeloRepuestoNew.getId());
//                repuesto.setModeloRepuesto(modeloRepuestoNew);
//            }
//            List<IngresoRepuesto> attachedLs_ingresosNew = new ArrayList<IngresoRepuesto>();
//            for (IngresoRepuesto ls_ingresosNewIngresoRepuestoToAttach : ls_ingresosNew) {
//                ls_ingresosNewIngresoRepuestoToAttach = em.getReference(ls_ingresosNewIngresoRepuestoToAttach.getClass(), ls_ingresosNewIngresoRepuestoToAttach.getId());
//                attachedLs_ingresosNew.add(ls_ingresosNewIngresoRepuestoToAttach);
//            }
//            ls_ingresosNew = attachedLs_ingresosNew;
//            repuesto.setLs_ingresos(ls_ingresosNew);
//            List<CambioDeRepuestos> attachedLs_cambiosNew = new ArrayList<CambioDeRepuestos>();
//            for (CambioDeRepuestos ls_cambiosNewCambioDeRepuestosToAttach : ls_cambiosNew) {
//                ls_cambiosNewCambioDeRepuestosToAttach = em.getReference(ls_cambiosNewCambioDeRepuestosToAttach.getClass(), ls_cambiosNewCambioDeRepuestosToAttach.getId());
//                attachedLs_cambiosNew.add(ls_cambiosNewCambioDeRepuestosToAttach);
//            }
//            ls_cambiosNew = attachedLs_cambiosNew;
//            repuesto.setLs_cambios(ls_cambiosNew);
//            repuesto = em.merge(repuesto);
//            if (modeloRepuestoOld != null && !modeloRepuestoOld.equals(modeloRepuestoNew)) {
//                modeloRepuestoOld.getLs_repuestos().remove(repuesto);
//                modeloRepuestoOld = em.merge(modeloRepuestoOld);
//            }
//            if (modeloRepuestoNew != null && !modeloRepuestoNew.equals(modeloRepuestoOld)) {
//                modeloRepuestoNew.getLs_repuestos().add(repuesto);
//                modeloRepuestoNew = em.merge(modeloRepuestoNew);
//            }
//            for (IngresoRepuesto ls_ingresosOldIngresoRepuesto : ls_ingresosOld) {
//                if (!ls_ingresosNew.contains(ls_ingresosOldIngresoRepuesto)) {
//                    ls_ingresosOldIngresoRepuesto.setRepuesto(null);
//                    ls_ingresosOldIngresoRepuesto = em.merge(ls_ingresosOldIngresoRepuesto);
//                }
//            }
//            for (IngresoRepuesto ls_ingresosNewIngresoRepuesto : ls_ingresosNew) {
//                if (!ls_ingresosOld.contains(ls_ingresosNewIngresoRepuesto)) {
//                    Repuesto oldRepuestoOfLs_ingresosNewIngresoRepuesto = ls_ingresosNewIngresoRepuesto.getRepuesto();
//                    ls_ingresosNewIngresoRepuesto.setRepuesto(repuesto);
//                    ls_ingresosNewIngresoRepuesto = em.merge(ls_ingresosNewIngresoRepuesto);
//                    if (oldRepuestoOfLs_ingresosNewIngresoRepuesto != null && !oldRepuestoOfLs_ingresosNewIngresoRepuesto.equals(repuesto)) {
//                        oldRepuestoOfLs_ingresosNewIngresoRepuesto.getLs_ingresos().remove(ls_ingresosNewIngresoRepuesto);
//                        oldRepuestoOfLs_ingresosNewIngresoRepuesto = em.merge(oldRepuestoOfLs_ingresosNewIngresoRepuesto);
//                    }
//                }
//            }
//            for (CambioDeRepuestos ls_cambiosOldCambioDeRepuestos : ls_cambiosOld) {
//                if (!ls_cambiosNew.contains(ls_cambiosOldCambioDeRepuestos)) {
//                    ls_cambiosOldCambioDeRepuestos.setRepuesto(null);
//                    ls_cambiosOldCambioDeRepuestos = em.merge(ls_cambiosOldCambioDeRepuestos);
//                }
//            }
//            for (CambioDeRepuestos ls_cambiosNewCambioDeRepuestos : ls_cambiosNew) {
//                if (!ls_cambiosOld.contains(ls_cambiosNewCambioDeRepuestos)) {
//                    Repuesto oldRepuestoOfLs_cambiosNewCambioDeRepuestos = ls_cambiosNewCambioDeRepuestos.getRepuesto();
//                    ls_cambiosNewCambioDeRepuestos.setRepuesto(repuesto);
//                    ls_cambiosNewCambioDeRepuestos = em.merge(ls_cambiosNewCambioDeRepuestos);
//                    if (oldRepuestoOfLs_cambiosNewCambioDeRepuestos != null && !oldRepuestoOfLs_cambiosNewCambioDeRepuestos.equals(repuesto)) {
//                        oldRepuestoOfLs_cambiosNewCambioDeRepuestos.getLs_cambios().remove(ls_cambiosNewCambioDeRepuestos);
//                        oldRepuestoOfLs_cambiosNewCambioDeRepuestos = em.merge(oldRepuestoOfLs_cambiosNewCambioDeRepuestos);
//                    }
//                }
//            }
//            em.getTransaction().commit();
            em = getEntityManager();
            em.getTransaction().begin();
            repuesto = em.merge(repuesto);
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Long id = repuesto.getId();
                if (findRepuesto(id) == null) {
                    throw new NonexistentEntityException("The repuesto with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Long id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Repuesto repuesto;
            try {
                repuesto = em.getReference(Repuesto.class, id);
                repuesto.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The repuesto with id " + id + " no longer exists.", enfe);
            }
            ModeloRepuesto modeloRepuesto = repuesto.getModeloRepuesto();
            if (modeloRepuesto != null) {
                modeloRepuesto.getLs_repuestos().remove(repuesto);
                modeloRepuesto = em.merge(modeloRepuesto);
            }
            List<IngresoRepuesto> ls_ingresos = repuesto.getLs_ingresos();
            for (IngresoRepuesto ls_ingresosIngresoRepuesto : ls_ingresos) {
                ls_ingresosIngresoRepuesto.setRepuesto(null);
                ls_ingresosIngresoRepuesto = em.merge(ls_ingresosIngresoRepuesto);
            }
            List<CambioDeRepuestos> ls_cambios = repuesto.getLs_cambios();
            for (CambioDeRepuestos ls_cambiosCambioDeRepuestos : ls_cambios) {
                ls_cambiosCambioDeRepuestos.setRepuesto(null);
                ls_cambiosCambioDeRepuestos = em.merge(ls_cambiosCambioDeRepuestos);
            }
            em.remove(repuesto);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Repuesto> findRepuestoEntities() {
        return findRepuestoEntities(true, -1, -1);
    }

    public List<Repuesto> findRepuestoEntities(int maxResults, int firstResult) {
        return findRepuestoEntities(false, maxResults, firstResult);
    }

    private List<Repuesto> findRepuestoEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Repuesto.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Repuesto findRepuesto(Long id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Repuesto.class, id);
        } finally {
            em.close();
        }
    }

    public int getRepuestoCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Repuesto> rt = cq.from(Repuesto.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

    public Repuesto findRepuestoPorCodigo(String nro_parte) {
        EntityManager em = getEntityManager();
        List<Repuesto> result = null;
        try {
            String jpql = "";
            jpql = "SELECT a FROM Repuesto a WHERE a.nro_parte LIKE :nro";
            Query query = em.createQuery(jpql);
            query.setParameter("nro", nro_parte);
            result = query.getResultList();
            if (!result.isEmpty()) {
                return result.get(0);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    //Mis metodos
    public List<Repuesto> getRepuestosLike(String value, int parametro) {
        EntityManager em = getEntityManager();
        List<Repuesto> result = null;
        try {
            String jpql = "";
            switch (parametro) {
                case RepuestoJpaController.NRO_PARTE:
                    jpql = "SELECT a FROM Repuesto a WHERE a.nro_parte LIKE :nro";
                    break;
                case RepuestoJpaController.DESCRIPCION:
                    jpql = "SELECT a FROM Repuesto a WHERE a.descripcion LIKE :nro";
                    break;
            }
            Query query = em.createQuery(jpql);
            query.setParameter("nro", "%" + value + "%");
            result = query.getResultList();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (result);
    }

    public boolean yaExiste(String value, int parametro, Long id_excepcion) {
        EntityManager em = getEntityManager();
        List<Repuesto> result = null;
        try {
            String jpql = "";
            switch (parametro) {
                case RepuestoJpaController.NRO_PARTE:
                    jpql = "SELECT a FROM Repuesto a WHERE a.nro_parte =:nro";
                    break;
                case RepuestoJpaController.DESCRIPCION:
                    jpql = "SELECT a FROM Repuesto a WHERE a.descripcion =:nro";
                    break;
            }
            Query query = em.createQuery(jpql);
            query.setParameter("nro", value);
            result = query.getResultList();
            if (result.isEmpty()) {
                return false;
            } else {
                for (Repuesto v : result) {
                    if (v.getId().equals(id_excepcion)) {
                        return false;
                    }
                }
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    public List<Repuesto> getRepuestosPor(String value, String parametro) {
        EntityManager em = getEntityManager();
        List<Repuesto> result = null;
        try {
            String jpql = "";
            switch (parametro) {
                case "Proveedor":
                    jpql = "SELECT ve FROM Repuesto ve JOIN ve.proveedorRepuesto pro WHERE pro.descripcion =:valor";
                    break;
                case "Categoria":
                    jpql = "SELECT ve FROM Repuesto ve JOIN ve.categoriaRepuesto cat WHERE cat.descripcion =:valor";
                    break;
                case "Marca":
                    jpql = "SELECT ve FROM Repuesto ve JOIN ve.modeloRepuesto model JOIN model.marca mar WHERE mar.descripcion =:valor";
                    break;
            }
            Query query = em.createQuery(jpql);
            query.setParameter("valor", value);
            result = query.getResultList();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return (result);
    }

}
